/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_RTSP_SESSION_H
#define MK_RTSP_SESSION_H
#include "MkRtspRequest.h"
#include "MkRtspAuthenticator.h"
#include "MkMedia/MkMediaSource.h"
#include "MkMedia/MkMediaConsumer.h"
#include "MkRtspSubSession.h"
#include "MkTcp/MkTcpSession.h"
#include "MkRtspUtil.h"
#include "MkSdp/MkSdp.h"

class CMkRtspServer;
class CMkMediaSource;
class CMkRtspConsumer;
class CMkRtspPublisherSource;
class MkApi CMkRtspSession : public CMkTcpSession
{
public:
    CMkRtspSession(CMkEvent *pEvent, CMkTimer* pTimer, CMkRtspServer* pServer,CMkRtpUdpServer* pUdpServer, const MkMediaCallbacks& MediaCbs);
    virtual ~CMkRtspSession();
    Uint32 SendEsPacket(const MkEsPacket& EsPacket, const CMkVideoParam& VideoParam, const CMkAudioParam& AudioParam);
protected:
    static void OnSubSessionSetupDelay(void *lParam);
private:
    BOOL IsAllSubSessionSetup();
    Uint32 SendRtp(CMkRtspSubSession* pSubSession, CMkRtpPacket& RtpPacket, const MkEsPacket& EsPacket);
    Uint32 SendH264Rtp(CMkRtspSubSession* pSubSession, CMkRtpPacket& RtpPacket, const MkEsPacket& EsPacket);
    Uint32 SendH265Rtp(CMkRtspSubSession* pSubSession, CMkRtpPacket& RtpPacket, const MkEsPacket& EsPacket);
    Uint32 SendAacRtp(CMkRtspSubSession* pSubSession, CMkRtpPacket& RtpPacket, const MkEsPacket& EsPacket);
    Uint32 SendRtpPacket(CMkRtspSubSession* pSubSession, const CMkRtpPacket& RtpPacket);
private:
    Uint32 OnRecv() override;
    Uint32 OnEventRemoved() override;
    Uint32 Check(const CMkTime& NowTime) override;
    Uint32 OnRtcpPacket(const CMkRtcpPacket& RtcpPacket, const MkString& Host, Uint16 Port);
    Uint32 OnRtpPacket(const MkCodecType& Codec, const CMkRtpPacket& RtpPacket, const MkString& Host, Uint16 Port);

    Uint32 ParseRtspFrame(Uint8* pBuf, Uint32 nLen, OUT Uint32& nUsed);
    Uint32 ParseRtspMessage(Uint8* pBuf, Uint32 nLen, OUT Uint32& nUsed);
    Uint32 OnOption(const CMkRtspRequest& Req);
    Uint32 OnDescribe(const CMkRtspRequest& Req);
    Uint32 OnSetUp(const CMkRtspRequest& Req);
    Uint32 OnPlay(const CMkRtspRequest& Req);
    Uint32 OnAnnounce(const CMkRtspRequest& Req);
    Uint32 OnTearDown(const CMkRtspRequest& Req);
    Uint32 OnPause(const CMkRtspRequest& Req);
    Uint32 OnRecord(const CMkRtspRequest& Req);
    Uint32 OnSetParameter(const CMkRtspRequest& Req);
    Uint32 OnGetParameter(const CMkRtspRequest& Req);
    Uint32 SendResponse(const CMkRtspRequest& Req, const MkRtspStatusCode& RtspStatus, const MkMap<MkRtspHeaderType, MkString>& MapHeader = MkMap<MkRtspHeaderType, MkString>(), const MkString& RtspBody = "", const MkMapString& ExternHeader = MkMapString());
private:
    Uint32 RemoveH264or5EmulationBytes(Uint8* pTo, Uint32 ToSize, const Uint8* pFrom, Uint32 FromSize);
private:
    MkMediaCallbacks                                m_MediaCbs;
    CMkRtpUdpServer*                                m_pUdpServer;
    Uint8*                                          m_pRecvBuffer;
    Uint32                                          m_nMaxLen;
    Uint32                                          m_nOffset;
    Uint8*                                          m_pPacketBuffer;
    Uint32                                          m_nPacketOffset;
    Uint32                                          m_nPacketMaxLen;
    BOOL                                            m_bStreamTcp;
    CMkRtspAuthenticator	                        *m_pAuthor;
    CMkRtspConsumer*                                m_pRtspConsumer;
    CMkRtspPublisherSource*                         m_pRtspPublishSource;
    MkString                                        m_PlaySession;
    MkUnorderedMap<Uint32, CMkRtspSubSession*>      m_MapSubsession;

    MkString                                        m_SourceSession;
    MkString                                        m_Path;
    MkString                                        m_Host;
    Uint32                                          m_TimeOut;
    BOOL                                            m_bPlaying;
};


#endif